import typing

import CAAMain
import json
from pathlib import Path
import os


def get_normalized_path(raw_path_str: str) -> str:
    path = Path(raw_path_str)

    if '/' in raw_path_str and '\\' not in raw_path_str:
        # 纯 UNIX 风格
        return path.as_posix().rstrip('/') + '/'  # 强制用 /
    elif '\\' in raw_path_str or ':' in raw_path_str:
        # Windows 风格（如 C:\...）
        return str(path).rstrip('\\') + '\\'
    else:
        # 默认使用当前系统风格
        return str(path) + os.sep


# class CA:
#     def __init__(self):
class UpdateDocumentReq:
    def __init__(self, aoName: str, revision: str, title: str, fileName: str, serverPath: str, username: str):
        self.aoName = aoName
        self.revision = revision
        self.title = title
        self.fileName = fileName
        self.serverPath = serverPath
        self.username = username


class AORemote:

    def __init__(self, configPath):
        self.configPath = configPath

        # 读取 JSON 文件并解析为 Python 对象（字典/列表）
        with open(configPath, 'r', encoding='utf-8') as file:
            json_obj = json.load(file)  # 直接解析文件内容

        self.host = json_obj['host']
        self.username = json_obj['username']
        self.password = json_obj['password']

    def getDocuments(self, reqList: []) -> []:
        baseUrl = '/resources/caasample/basicrestws/GetBOPDocuments'
        appUrlList = []
        for req in reqList:
            url = f"{baseUrl}?type={req['type']}&name={req['name']}&revision={req['revision']}&relation={req['relation']}"
            appUrlList.append(url)
        return CAAMain.GET(self.host, self.username, self.password, appUrlList)

    # {
    #             "msg": "OK",
    #             "objectIds": "DELLmiHeaderOperationReference,hop-25x-00000001,A,10139.6781.26993.25595",
    #             "data": [{
    #                     "level": "1",
    #                     "name": "DOC-0000004",
    #                     "id": "58176.27398.26993.26166",
    #                     "owner": "admin_platform",
    #                     "id[connection]": "10139.6781.26993.26244",
    #                     "relationship": "Reference Document",
    #                     "current": "IN_WORK",
    #                     "attribute[Title]": "123",
    #                     "type": "xiziWorkInstruction",
    #                     "revision": "0",
    #                     "project": "Common Space"
    #                 }, {
    #                     "level": "1",
    #                     "name": "DOC-0000005",
    #                     "id": "58176.27398.26993.26557",
    #                     "owner": "admin_platform",
    #                     "id[connection]": "10139.6781.26993.26620",
    #                     "relationship": "Reference Document",
    #                     "current": "IN_WORK",
    #                     "attribute[Title]": "456",
    #                     "type": "xiziWorkInstruction",
    #                     "revision": "0",
    #                     "project": "Common Space"
    #                 }
    #             ]
    #         }

    def getCA(self, aoId: str, aoVersion: str):
        url1 = f"/resources/caasample/basicrestws/GetChangeDocuments?type=DELLmiHeaderOperationReference&name={aoId}&revision={aoVersion}&functionality=isChangeActionTab"
        appPathList = [url1]

        aoChangeRsStrList = CAAMain.GET(self.host, self.username, self.password, appPathList)
        if len(aoChangeRsStrList) < 1:
            return {}

        aoChangeRsStr = aoChangeRsStrList[0]
        aoChangesRsJson = json.loads(aoChangeRsStr)
        # with open('D:\\workspace\\xizi\\AO\\testCA.json', 'r', encoding='utf-8') as f:
        #     aoChangesRsJson = json.load(f)

        if len(aoChangesRsJson) < 1:
            return {}

        _, aoCaInfo = next(iter(aoChangesRsJson.items()))

        if 'CA' not in aoCaInfo:
            return {}

        caInnerId = aoCaInfo['CA']['id']

        url2 = f"/resources/v1/modeler/dslc/changeaction/{caInnerId}"
        appPathList = [url2]
        caInfoRsStrList = CAAMain.GET(self.host, self.username, self.password, appPathList)
        if len(caInfoRsStrList) < 1:
            return {}

        caInfoStr = caInfoRsStrList[0]
        caInfoJson = json.loads(caInfoStr)

        return {
            'CA': caInfoJson,
            'Changes': aoCaInfo
        }

    def _postUploadFile(self, filePath: Path) -> {}:

        try:
            with open(str(filePath.absolute()), 'rb') as f:
                file_content = f.read()

            # output_dir = str(Path.cwd())

            # Assuming CAAMain.POST sends raw bytes if the last param is False,
            # and returns a single response string like CAAMain.PUT.
            response_str = CAAMain.POSTFile(
                self.host,
                self.username,
                self.password,
                f"/resources/uitc/tools/UploadFile?fileName={filePath.name}",
                file_content,  # Pass raw bytes as the body
                False
            )

            if response_str is None:
                return {"error": "No response string from server."}

            try:
                return json.loads(response_str)
            except json.JSONDecodeError:
                # If response is not JSON, return it wrapped in a dictionary
                return {"raw_response": response_str, "message": "Response was not valid JSON."}
            except TypeError:
                # This might happen if response_str is already a dict/list (e.g., if CAAMain.POST parsed it)
                if isinstance(response_str, (dict, list)):
                    return response_str
                return {"raw_response": str(response_str),
                        "message": "Response from CAAMain.POST was not a string or was empty."}

        except FileNotFoundError:
            return {"error": f"File not found: {filePath.absolute()}"}
        except Exception as e:
            return {"error": f"An error occurred during file upload: {str(e)}"}

    def _getUpdateDocument(self, req: UpdateDocumentReq):
        baseUrl = "/resources/caasample/basicrestws/UploadDocument"

        appUrlList = []

        aoName = req.aoName  # hop-25x-00000065
        revision = req.revision  # A
        docName = req.fileName.replace('.docx', '')  # AO_228C02BS0010
        # title = req.title  # 228C02BS0010
        title = req.fileName.replace('.docx', '')  # 228C02BS0010  25/11/11 改成 AO_ AR_ 开头
        fileName = req.fileName  # AO_228C02BS0010.docx
        path = req.serverPath  # /usr/DassaultSystemes/zsh/
        username = req.username

        # output_dir = str(Path.cwd())

        url = f"{baseUrl}?userName={username}&type=DELLmiHeaderOperationReference&name={aoName}&revision={revision}&docType=xiziWorkInstruction&docName={docName}&title={title}&fileName={fileName}&path={path}&relation=SpecificationDocument"
        appUrlList.append(url)

        rsList = CAAMain.GET(self.host, self.username, self.password, appUrlList)
        print(f"_getUpdateDocument: {appUrlList[0]}")
        if len(rsList) > 0:
            print(rsList[0])

    def uploadDocuments(self, filePath: Path, aoFileJson: typing.Dict):
        responseAO = self._postUploadFile(filePath)
        if 'data' not in responseAO:
            raise Exception(responseAO)
        aoServerPath = Path(responseAO['data'])

        output_path = get_normalized_path(str(aoServerPath.parent))

        req = UpdateDocumentReq(aoFileJson['reference']['PLM_ExternalID'], aoFileJson['reference']['revision'],
                                aoFileJson['reference']['V_Name'], filePath.name, output_path, aoFileJson['UserId'])
        self._getUpdateDocument(req)


if __name__ == '__main__':
    pathT = 'D:\\workspace\\xizi\\AO'

    # debug 使用
    # file_path = "C:\\Users\\Administrator\\Desktop\\current_dir.txt"
    # with open(file_path, 'w', encoding='utf-8') as file:
    #     file.write(pathT)

    # load_ini
    jsonPath = pathT + "\\output.json"
    remoteConfigPath = pathT + "\\connectionConfig.json"

    with open(jsonPath, "r", encoding="utf-8") as file:
        aoJson = json.load(file)

    remote = AORemote(remoteConfigPath)

    ao_file_path = Path("D:\\workspace\\xizi\\AO\\AO_228C02BS0070.docx")

    remote.uploadDocuments(ao_file_path, aoJson)

    # doc = remote.getDocuments({})
    # file_path = Path("C:\\Users\\Administrator\\Desktop\\3DE开发环境搭建说明书.docx")
    # doc = remote.upload_file(file_path)
    # print(doc)
    # remote.updateDoc()
    # ca = remote.getCA("hop-58803944-00000003")
    # remote.testPost()
    # print(ca)

    # getCA
    # {
    #     'CA': {
    #         'id': 'CD693D29E61700006807604A00000007',
    #         'cestamp': 'CD693D29E61700006807619D00000266',
    #         'policy': 'Change Action',
    #         'type': 'Change Action',
    #         'description': '123123',
    #         'title': 'NewCA',
    #         'name': 'CA-58803944-00000028',
    #         'state': 'In Approval',
    #         'owner': 'admin_platform',
    #         'organization': 'Company Name',
    #         'collabSpace': 'Common Space',
    #         'severity': 'Low',
    #         'Estimated Start Date': '',
    #         'Actual Start Date': '2025-04-22T05:30:00-0400',
    #         'Estimated Completion Date': '',
    #         'Actual Completion Date': '',
    #         'xmlApplicability': '',
    #         'txtApplicability': '',
    #         'onHold': False
    #     },
    #     'Changes': {
    #         'AO': {
    #             'name': 'hop-58803944-00000003',
    #             'REVISED BY': 'admin_platform',
    #             'id': '60514.56046.46311.59045',
    #             'type': 'DELLmiHeaderOperationReference',
    #             'Date': '4/22/2025 5:30:00 AM',
    #             'revision': 'A'
    #         },
    #         'CA': {
    #             'id[connection]': '5478.49656.20699.10899',
    #             'name': 'CA-58803944-00000028',
    #             'id': 'CD693D29E61700006807604A00000007',
    #             'CHANGE INSTRUCTIONS': '123123'
    #         },
    #         'signData': [{
    #             'attribute[Actual Completion Date]': '4/22/2025 5:30:00 AM',
    #             'name': 'admin_platform',
    #             'attribute[Route Sequence]': '0',
    #             'attribute[Title]': '设计'
    #         }, {
    #             'level': '1',
    #             'name': 'admin_platform',
    #             'id': '5478.49656.60515.15206',
    #             'attribute[Actual Completion Date]': '',
    #             'id[connection]': '5478.49656.20699.11638',
    #             'relationship': 'Route Node',
    #             'current': 'Active',
    #             'attribute[Title]': 'Approval task to review changes done on Change Action : CA-58803944-00000028, titled : NewCA',
    #             'type': 'Person',
    #             'attribute[Route Sequence]': '1'
    #         }
    #         ]
    #     }
    # }
